package org.springframework.boot.autoconfigure.mock.core;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.mock.annotation.MockResponse;
import org.springframework.boot.autoconfigure.mock.handler.MockResponseHandler;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * Created by kl on 2017/12/29.
 * Content :给添加@KLock切面加锁处理
 */
@Aspect
@Order(0)
@Component
public class MockResponseAspect {

    private static final Logger logger = LoggerFactory.getLogger(MockResponseAspect.class);

    @Autowired
    private MockResponseHandler mockResponseHandler;


    @Around(value = "@annotation(mockResponse)")
    public Object around(ProceedingJoinPoint joinPoint, MockResponse mockResponse) throws Throwable {
        // 校验是否启用mock响应
        final boolean require = mockResponse.require();
        if (!require) {
            logger.info("Mock response wasn't require, go proceed...");
            return joinPoint.proceed();
        }
        // 调用mock handler进行响应处理
        return mockResponseHandler.process(joinPoint, mockResponse);
    }

    @AfterReturning(value = "@annotation(mockResponse)")
    public void afterReturning(JoinPoint joinPoint, MockResponse mockResponse) throws Throwable {
        logger.info("mock response return...");
    }

    @AfterThrowing(value = "@annotation(mockResponse)", throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, MockResponse mockResponse, Throwable ex) throws Throwable {
        logger.error("Mock process met error, mock annotation value: {}, error: ", mockResponse.value(), ex);
        throw ex;
    }
}
